﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace MuYue.Common {
    /// <summary>
    /// 线程队列模型
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class ThreadModel<T> {

        /// <summary>
        /// 构造函数
        /// 创建的时候启动Log处理线程来实现对调用方的最小影响
        /// 同时因为要调用消息队列所以需要使用Lock
        /// </summary>
        public ThreadModel() {
            new Task(WorkingThread).Start();
        }

        /// <summary>
        /// LOG线程等待标记 用来触发写消息写入了
        /// </summary>
        private readonly AutoResetEvent wait = new AutoResetEvent(true);

        /// <summary>
        /// 线程安全的队列
        /// </summary>
        ConcurrentQueue<T> wq = new ConcurrentQueue<T>();

        /// <summary>
        /// 控制Log线程的运行
        /// </summary>
        private bool _working = true;

        /// <summary>
        /// LOG实际处理线程
        /// </summary>
        private void WorkingThread() {
            T tModle;
            Console.WriteLine("ok!!!");
            while (_working) {
                if (!wq.IsEmpty) {
                    if (wq.TryDequeue(out tModle) && DealModelEvent != null) {
                        DealModelEvent(tModle);
                    }
                }
                else {
                    wait.WaitOne();
                }
            }
        }

        /// <summary>
        /// 日志消息处理托管
        /// </summary>
        /// <param name="message"></param>
        public delegate void DealEvent(T tModle);

        /// <summary>
        /// 接口 对消息的处理过程
        /// </summary>
        public event DealEvent DealModelEvent;

        /// <summary>
        /// 将消息写入消息队列里
        /// </summary>
        /// <param name="tModle"></param>
        /// <param name="level"></param>
        public void Append(T tModle) {
            wq.Enqueue(tModle);
            wait.Set();
        }

        #region IDisposable 成员

        /// <summary>
        /// 释放掉占用的资源
        /// </summary>
        public void Dispose() {
            if (_working) {
                _working = false;
                wait.Set();
                wait.Dispose();
            }
        }

        #endregion


        public int Busy { get { return wq.Count; } }
    }
}
